/* @formatter:off
 * Copyright (c) 2011 Lucas <lucas03093@gmail.com>
 * 
 * 
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
/* @formatter:on */

package nu.korkad.daytracker.activity;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;

import nu.korkad.daytracker.R;
import nu.korkad.daytracker.database.DataHelper;
import nu.korkad.daytracker.info.Dates;
import nu.korkad.daytracker.info.Network;
import nu.korkad.daytracker.io.IO;
import nu.korkad.daytracker.settings.Config;
import nu.korkad.daytracker.settings.PrefStore;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.database.Cursor;
import android.os.Bundle;
import android.text.ClipboardManager;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.ListView;
import android.widget.Toast;

import com.bugsense.trace.BugSenseHandler;
import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.android.AndroidAuthSession;
import com.dropbox.client2.session.AppKeyPair;

public class Archive extends ListActivity
{
    private String[]                       company;
    private String[]                       text;
    private String[]                       ids;
    private String[]                       checkin;
    private String[]                       checkout;
    private String[]                       unread;
    private Activity                       context;
    private DropboxAPI<AndroidAuthSession> mDBApi;
    
    /** Called when the activity is first created. */
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        
        // Crash report
        if (PrefStore.getCrashReport(this))
            BugSenseHandler.setup(this, Config.APPLICATION_BUGSENSE);
        
        // Create arraylists
        ArrayList<String> company = new ArrayList<String>();
        ArrayList<String> text = new ArrayList<String>();
        ArrayList<String> ids = new ArrayList<String>();
        ArrayList<String> checkin = new ArrayList<String>();
        ArrayList<String> checkout = new ArrayList<String>();
        ArrayList<String> unread = new ArrayList<String>();
        
        context = this;
        
        // Get datahelper
        DataHelper dh = new DataHelper(this);
        
        // Get data
        Cursor c = dh.selectAll(0, 50);
        c.moveToFirst();
        while (c.isAfterLast() == false)
        {
            if (c.getInt(0) != PrefStore.getCurrentId(this))
            {
                ids.add(Integer.toString(c.getInt(0)));
                company.add(c.getString(1));
                checkin.add(Integer.toString(c.getInt(2)));
                checkout.add(Integer.toString(c.getInt(3)));
                text.add(c.getString(4));
                unread.add(Integer.toString(c.getInt(5)));
            }
            
            c.moveToNext();
        }
        
        // Close cursor
        if (c != null && !c.isClosed())
            c.close();
        
        // Close dh
        dh.close();
        dh = null;
        
        // Create string arrays
        this.ids = new String[ids.size()];
        this.company = new String[company.size()];
        this.checkin = new String[checkin.size()];
        this.checkout = new String[checkout.size()];
        this.text = new String[text.size()];
        this.unread = new String[unread.size()];
        
        // Populate string arrays
        ids.toArray(this.ids);
        company.toArray(this.company);
        checkin.toArray(this.checkin);
        checkout.toArray(this.checkout);
        text.toArray(this.text);
        unread.toArray(this.unread);
        
        // Register for context menu
        registerForContextMenu(getListView());
        
        // Keep screen on
        getListView().setKeepScreenOn(true);
        
        // Create list view
        setListAdapter(new ListView_Archive(this, this.company, this.checkin, this.checkout, this.text, this.unread));
        
    }
    
    @Override
    protected void onListItemClick(ListView l, final View v, final int position, long id)
    {
        super.onListItemClick(l, v, position, id);
        
        // Get unread button text
        String unreadButton = "";
        if (unread[position].equals("1"))
            unreadButton = getString(R.string.dialog_archive_button_mark_read);
        else
            unreadButton = getString(R.string.dialog_archive_button_mark_unread);
        
        // Create popup
        nu.korkad.daytracker.alertdialog.Archive
                .create(this, company[position], text[position], Long.parseLong(checkin[position].trim()),
                        Long.parseLong(checkout[position].trim()), Long.parseLong(ids[position].trim()),
                        Integer.parseInt(unread[position].trim()))
                .setNeutralButton(getString(R.string.dialog_archive_button_clipboard), new OnClickListener()
                {
                    @Override
                    public void onClick(DialogInterface dialog, int which)
                    {
                        // Get clipboard
                        ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
                        
                        // Set clipboard text
                        clipboard.setText(getString(R.string.dialog_archive_text_id)
                                + " "
                                + ids[position]
                                + "\n"
                                + getString(R.string.dialog_archive_text_company)
                                + " "
                                + company[position]
                                + "\n"
                                + getString(R.string.dialog_archive_text_checkin)
                                + " "
                                + Dates.getArchiveDate(Long.parseLong(checkin[position].trim()), context)
                                + "\n"
                                + getString(R.string.dialog_archive_text_checkout)
                                + " "
                                + Dates.getArchiveDate(Long.parseLong(checkout[position].trim()), context)
                                + "\n"
                                + getString(R.string.dialog_archive_text_duration)
                                + " "
                                + Dates.getDuration(Long.parseLong(checkin[position].trim()) * 1000,
                                        Long.parseLong(checkout[position].trim()) * 1000, context) + "\n\n"
                                + getString(R.string.dialog_archive_text_report) + "\n" + text[position]);
                        
                        // Notify user
                        Toast.makeText(context, R.string.toast_archive_clipboard, 500).show();
                    }
                }).setNegativeButton(unreadButton, new OnClickListener()
                {
                    @Override
                    public void onClick(DialogInterface dialog, int which)
                    {
                        // Get DH
                        DataHelper dh = new DataHelper(getBaseContext());
                        
                        // Update unread column
                        if (unread[position].equals("1"))
                        {
                            dh.updateUnread(0, Long.parseLong(ids[position]));
                            unread[position] = "0";
                        }
                        else
                        {
                            dh.updateUnread(1, Long.parseLong(ids[position]));
                            unread[position] = "1";
                        }
                        
                        // Close dh
                        if (dh != null)
                            dh.close();
                        
                        // Set new list adapter
                        setListAdapter(new ListView_Archive(context, company, checkin, checkout, text, unread));
                    }
                }).show();
    }
    
    /**
     * Spawns a new thread to remove entry from database, removes the entry from current arraylists and rebuilds the listadapter.
     * 
     * @param info
     *            AdapterContextMenuInfo
     */
    public void deleteEntry(final AdapterContextMenuInfo info)
    {
        // Save id for db thread
        final String id = ids[info.position];
        
        // Spawn new thread
        new Thread(new Runnable()
        {
            @Override
            public void run()
            {
                // Get dh
                DataHelper dh = new DataHelper(context);
                
                // Delete row
                dh.deleteRow(Long.parseLong(id.trim()));
                
                // Close dh
                if (dh != null)
                {
                    dh.close();
                    dh = null;
                }
            }
        }, "database").start();
        
        // Temp arraylists
        ArrayList<String> ids = new ArrayList<String>(Arrays.asList(this.ids));
        ArrayList<String> checkin = new ArrayList<String>(Arrays.asList(this.checkin));
        ArrayList<String> checkout = new ArrayList<String>(Arrays.asList(this.checkout));
        ArrayList<String> text = new ArrayList<String>(Arrays.asList(this.text));
        ArrayList<String> company = new ArrayList<String>(Arrays.asList(this.company));
        ArrayList<String> unread = new ArrayList<String>(Arrays.asList(this.unread));
        
        // Remove deleted row
        ids.remove(info.position);
        checkin.remove(info.position);
        checkout.remove(info.position);
        text.remove(info.position);
        company.remove(info.position);
        unread.remove(info.position);
        
        // Recreate string arrays
        this.ids = new String[ids.size()];
        this.company = new String[company.size()];
        this.checkin = new String[checkin.size()];
        this.checkout = new String[checkout.size()];
        this.text = new String[text.size()];
        this.unread = new String[unread.size()];
        
        // Populate string arrays
        ids.toArray(this.ids);
        company.toArray(this.company);
        checkin.toArray(this.checkin);
        checkout.toArray(this.checkout);
        text.toArray(this.text);
        unread.toArray(this.unread);
        
        // Null temp strings
        ids = null;
        checkin = null;
        checkout = null;
        text = null;
        company = null;
        unread = null;
        
        // Create new list adapter
        setListAdapter(new ListView_Archive(this, this.company, this.checkin, this.checkout, this.text, this.unread));
    }
    
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
    {
        super.onCreateContextMenu(menu, v, menuInfo);
        
        // Info about the entry the user selected
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
        
        // Add dynamic menu entry
        if (this.unread[info.position].equals("0"))
            menu.add(Menu.NONE, Config.MENU_ARCHIVE_CONTEXT_MARK, 0, R.string.menu_archive_context_mark_unread);
        else
            menu.add(Menu.NONE, Config.MENU_ARCHIVE_CONTEXT_MARK, 0, R.string.menu_archive_context_mark_read);
        
        // Setup layout
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.archive_context, menu);
    }
    
    @Override
    public boolean onContextItemSelected(MenuItem item)
    {
        final AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        
        switch (item.getItemId())
        {
            case Config.MENU_ARCHIVE_CONTEXT_MARK:
                // Get DH
                DataHelper dh = new DataHelper(getBaseContext());
                
                // Update unread column
                if (unread[info.position].equals("1"))
                {
                    dh.updateUnread(0, Long.parseLong(ids[info.position]));
                    unread[info.position] = "0";
                }
                else
                {
                    dh.updateUnread(1, Long.parseLong(ids[info.position]));
                    unread[info.position] = "1";
                }
                
                // Close dh
                if (dh != null)
                    dh.close();
                
                // Set new list adapter
                setListAdapter(new ListView_Archive(context, company, checkin, checkout, text, unread));
                break;
            
            case R.id.menu_archive_context_show: // Show alertdialog
                nu.korkad.daytracker.alertdialog.Archive.create(this, company[info.position], text[info.position],
                        Long.parseLong(checkin[info.position].trim()), Long.parseLong(checkout[info.position].trim()),
                        Long.parseLong(ids[info.position].trim()), Integer.parseInt(unread[info.position].trim())).show();
                break;
            
            case R.id.menu_archive_context_delete: // Delete row
                
                new AlertDialog.Builder(context).setTitle(getString(R.string.dialog_archive_text_delete_title)).setCancelable(true)
                        .setPositiveButton(getString(R.string.Yes), new OnClickListener()
                        {
                            @Override
                            public void onClick(DialogInterface dialog, int which)
                            {
                                deleteEntry(info);
                            }
                        }).setNegativeButton(getString(R.string.No), null).create().show();
                break;
            
            case R.id.menu_archive_context_export_dropbox: // Upload report to dropbox
                // Check network availability
                if (!Network.networkCheck(this).equals("ok"))
                    Toast.makeText(this, Network.networkCheck(this), Toast.LENGTH_LONG).show();
                else
                {
                    // Get dropbox stuff
                    AppKeyPair appKeys = new AppKeyPair(Config.DROPBOX_APP_KEY, Config.DROPBOX_APP_SECRET);
                    AndroidAuthSession session = new AndroidAuthSession(appKeys, Config.DROPBOX_ACCESS_TYPE);
                    mDBApi = new DropboxAPI<AndroidAuthSession>(session);
                    
                    // Check if user is authenticated against dropbox
                    if (PrefStore.getDropboxKey(this).equals(""))
                        Toast.makeText(this, getString(R.string.toast_dropbox_credentials), Toast.LENGTH_SHORT).show();
                    else
                    {
                        // Notify user
                        Toast.makeText(context, String.format(getString(R.string.toast_archive_export_dropbox), ids[info.position]),
                                Toast.LENGTH_SHORT).show();
                        
                        // Copy report
                        IO.exportReportToDropbox(this.text[info.position], this.company[info.position], this.ids[info.position],
                                Long.parseLong(this.checkin[info.position].trim()), Long.parseLong(this.checkout[info.position].trim()),
                                new File(getCacheDir() + File.separator + this.ids[info.position] + ".txt"), context, mDBApi);
                    }
                }
                break;
            // TODO1: Add edit function
            default:
                return super.onContextItemSelected(item);
        }
        
        return true;
    }
}